﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Net;
using System.Net.NetworkInformation;
using System.Threading;

namespace DocManagerControls.Controls
{
    /// <summary>
    /// Logica di interazione per NetworkInfoControl.xaml
    /// </summary>
    public partial class NetworkInfoControl : BaseCusControl
    {
        static StringBuilder m_SBPing = new StringBuilder(400);
        static TextBox m_TextPing = null;

        public NetworkInfoControl()
        {
            InitializeComponent();

            txtDati.Text = getNetworkInfo();

            txtDati.Text += "\r\n" + string.Format("Gateway\t\t :\t{0}", GetGatewayID());

            txtDati.Text += "\r\n"+ getPcInfo();

            txtDati.Text += "\r\n" + GetTcpConnections();

            txtDati.Text += "\r\n" + getDriversDisponibili();
        }

        private static string getNetworkInfo()
        {
            StringBuilder sb = new StringBuilder(400); 
            IPHostEntry dati = Dns.GetHostEntry("");
            
            sb.AppendFormat("HostName\t :\t{0}", dati.HostName).AppendLine();

            foreach (var item in dati.AddressList)
	        {
                sb.AppendFormat("Indirizzo IP\t :\t{0} ",item ).AppendLine();
	        }
            return sb.ToString(); 
        }//fM

        private static string GetGatewayID()
        {
            string gatewayID= string.Empty;
 
            NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces();
            foreach (NetworkInterface adapter in adapters)
            {
                IPInterfaceProperties adapterProperties = adapter.GetIPProperties();
                GatewayIPAddressInformationCollection addresses = adapterProperties.GatewayAddresses;
                if (addresses.Count > 0)
                {
                    foreach (GatewayIPAddressInformation address in addresses)
                    {

                        if (string.IsNullOrEmpty(gatewayID))
                            gatewayID += address.Address.ToString();
                        else
                            gatewayID += address.Address.ToString() + "\r\n";

                    }
                }
            }

            return gatewayID;
        }//fM

        private static string getPcInfo()
        {
            StringBuilder sb = new StringBuilder(400); 
            var dischi = Environment.GetLogicalDrives() ;

            sb.AppendFormat("Username ?\t :\t{0}", Environment.UserName).AppendLine();
            sb.AppendFormat("Nome Utente\t :\t{0}", Environment.UserName).AppendLine();
            sb.AppendFormat("Nome Macchina\t :\t{0}", Environment.MachineName).AppendLine();
            sb.AppendFormat("Dominio\t\t :\t{0}", Environment.UserDomainName).AppendLine();
            
            sb.AppendFormat("OS 64 bit\t :\t{0}", Environment.Is64BitOperatingSystem).AppendLine();
            sb.AppendFormat("Proc. 64 bit \t :\t{0}", Environment.Is64BitProcess).AppendLine();

            sb.AppendFormat("OS version \t :\t{0}", Environment.OSVersion ).AppendLine();
            sb.AppendFormat("N° processori \t :\t{0}", Environment.ProcessorCount ).AppendLine();
            sb.AppendFormat("Net Version \t :\t{0}", Environment.Version ).AppendLine();
            sb.AppendFormat("WorkingSet \t :\t{0}", Environment.WorkingSet).AppendLine();
                        
            return sb.ToString(); 
        }//fm

        public static string getDriversDisponibili()
        {
            StringBuilder sb = new StringBuilder(400);
            var dischi = Environment.GetLogicalDrives();
            foreach (var item in dischi)
                sb.AppendFormat("Driver visibili\t :\t{0}", item).AppendLine();

            return sb.ToString();
        }//fM

        public static string GetTcpConnections()
        {
            StringBuilder sb = new StringBuilder(400); 
            IPGlobalProperties properties = IPGlobalProperties.GetIPGlobalProperties();            
            TcpConnectionInformation[] connections = properties.GetActiveTcpConnections();

            foreach (TcpConnectionInformation t in connections)
            {
                sb.AppendFormat("Local endpoint: {0} ", t.LocalEndPoint.Address).AppendLine();
                sb.AppendFormat("Remote endpoint: {0} ", t.RemoteEndPoint.Address).AppendLine();
                sb.AppendFormat("{0}", t.State).AppendLine();
            }

            return sb.ToString();

        }//fM
        
        //args[0] can be an IPaddress or host name.
        public static void pinga ( string pIpAdressOrHostName)
        {
            m_SBPing.Clear();
            m_TextPing.Text = "";

            if (string.IsNullOrEmpty(pIpAdressOrHostName))
            {
                m_SBPing.AppendLine("Ping needs a host or IP Address.");
                m_TextPing.Text = m_SBPing.ToString();
                m_SBPing.Clear();
                return;
            }

            string who = pIpAdressOrHostName;
            AutoResetEvent waiter = new AutoResetEvent(false);

            Ping pingSender = new Ping();

            // When the PingCompleted event is raised,
            // the PingCompletedCallback method is called.
            pingSender.PingCompleted += new PingCompletedEventHandler(PingCompletedCallback);

            // Create a buffer of 32 bytes of data to be transmitted.
            string data = "---------------------------------";
            byte[] buffer = Encoding.ASCII.GetBytes(data);

            // Wait 12 seconds for a reply.
            int timeout = 12000;

            // Set options for transmission:
            // The data can go through 64 gateways or routers
            // before it is destroyed, and the data packet
            // cannot be fragmented.
            PingOptions options = new PingOptions(64, true);

            m_SBPing.AppendFormat("Time to live\t:\t{0}", options.Ttl).AppendLine();
           
            // Send the ping asynchronously.
            // Use the waiter as the user token.
            // When the callback completes, it can wake up this thread.
            pingSender.SendAsync(who, timeout, buffer, options, waiter);

            // Prevent this example application from ending.
            // A real application should do something useful
            // when possible.
            
            //waiter.WaitOne();

            //sb.AppendFormat("Ping completato.").AppendLine();
            
        }//fM
        
        private static void PingCompletedCallback(object sender, PingCompletedEventArgs e)
        {
            // If the operation was canceled, display a message to the user.
            if (e.Cancelled)
            {
                m_SBPing.AppendFormat("Ping canceled.").AppendLine();

                // Let the main thread resume. 
                // UserToken is the AutoResetEvent object that the main thread 
                // is waiting for.
                ((AutoResetEvent)e.UserState).Set();
            }

            // If an error occurred, display the exception to the user.
            if (e.Error != null)
            {
                m_SBPing.AppendFormat("Ping failed:").AppendLine();
                m_SBPing.AppendFormat(e.Error.ToString());

                if(e.Error.InnerException != null)
                    m_SBPing.AppendFormat(e.Error.InnerException.ToString());


                // Let the main thread resume. 
                ((AutoResetEvent)e.UserState).Set();
            }

            PingReply reply = e.Reply;

            m_SBPing.AppendLine(" -- Ping Completato -- "); 
            DisplayReply(reply);

            // Let the main thread resume.
            ((AutoResetEvent)e.UserState).Set();
            
        }//fM

        public static void DisplayReply(PingReply reply)
        {
            if (reply == null)
            {
                m_TextPing.Text = m_SBPing.ToString();
                m_SBPing.Clear();
                return;
            }
            m_SBPing.AppendLine();
            m_SBPing.AppendFormat("Stato Ping\t:\t{0}", reply.Status).AppendLine("\r\n");
            if (reply.Status == IPStatus.Success)
            {
                m_SBPing.AppendFormat("Indirizzo\t:\t{0}", reply.Address.ToString()).AppendLine();
                m_SBPing.AppendFormat("RoundTrip time\t:\t{0}", reply.RoundtripTime).AppendLine();
                m_SBPing.AppendFormat("Time to live\t:\t{0}", reply.Options.Ttl).AppendLine();
                m_SBPing.AppendFormat("Non frammentato\t:\t{0}", reply.Options.DontFragment).AppendLine();
                m_SBPing.AppendFormat("Buffer size\t:\t{0}", reply.Buffer.Length).AppendLine();                
            }

            m_TextPing.Text = m_SBPing.ToString();
            m_SBPing.Clear();
        }

        private void btnStartPing_Click(object sender, RoutedEventArgs e)
        {
            //txtPingAdress.Text = "10.96.75.148";

            var adress = txtPingAdress.Text.Trim();
            if (string.IsNullOrEmpty(adress)) return;

            m_TextPing = txtPingResul;

            pinga(adress);
        }


    }//fC
}
